﻿using System;
using System.Web.UI.WebControls;
using System.Collections.Generic;
using System.Web.UI;
using System.Reflection;
using System.ComponentModel;



namespace MVCnExt.Web.UI.Ext
{
    public class ExtMenuItem : ExtMenuBaseItem
    {
        private List<ScriptReference> _references = new List<ScriptReference>();

        /// <summary>
        /// Registeres script dependencies with the page
        /// </summary>
        /// <remarks>
        /// This is dependent upon GetScriptDescriptors() being called first.
        /// Otherwise, child dependencies found within the 'items' collection
        /// won't get registered. At the moment this doesn't seem to be a problem
        /// as the .NET Framework (as well as this one) follow this pattern.
        /// 
        /// The reason for this dependency is the 'items' collection. The objects
        /// in the collection aren't instantiated the same way as a control found
        /// in the page or body templates. An object in the collection has no
        /// reference to Page or ScriptManager and it's page events aren't called.
        /// I don't think this is a problem, since the 'items' collection are objects
        /// don't begin their life-cycle until the page is loaded anyway.
        /// </remarks>
        public override List<ScriptReference> GetScriptReferences()
        {
            _references.AddRange(base.GetScriptReferences());

            return _references;
        }

        public override IList<ScriptDescriptor> GetScriptDescriptors()
        {
            IList<ScriptDescriptor> list = base.GetScriptDescriptors();

            ScriptControlDescriptorBase desc = (ScriptControlDescriptorBase)list[0];

            desc.Type = "Ext.menu.Item";

            String[] properties = new String[]{
                "href", "hrefTarget", "icon", 
                "iconCls", "itemCls", "showDelay",
                "text"
            };

            Type component = typeof(ExtMenuItem);

            foreach (String property in properties)
            {
                PropertyInfo i = component.GetProperty(property);

                if (i == null)
                    throw new InvalidOperationException(String.Format("Property not found, 'Ext.menu.Item.{0}'", property));

                Object value = i.GetValue(this, null);

                if (value == null)
                    continue;

                if (!(value is String))
                    desc.AddPropertyBase(property, value);
                else
                    desc.AddPropertyBase(property, String.Format("'{0}'", value));
            }

            //menu
            if (menu != null)
            {
                // items script
                ScriptControlDescriptorBase descriptor = (ScriptControlDescriptorBase)menu.GetScriptDescriptors()[0];

                // get the items's list of script dependencies
                _references.AddRange(menu.GetScriptReferences());

                // write config script to properties
                desc.AddPropertyBase("menu", descriptor.WriteScript(ScriptType.NewOnly));
            }

            return list;
        }

        public String href { get; set; }

        public String hrefTarget { get; set; }

        public String icon { get; set; }

        public String iconCls { get; set; }

        public String itemCls { get; set; }

        [NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public ExtMenu menu { get; set; }

        public Int32? showDelay { get; set; }

        public String text { get; set; }
    }
}
